<?php
/**
 * Mô tả:
 * 
 * Lớp CRecord là lớp cơ sở
 * 
 * @access public
 * @version : 1.0
 * @since June-2008
 * @package : lib
 * @subpackage struct
 * @name :  CRecord
 * @todo:  Lớp CRecord biến mảng thành một đối tượng (object).Thao tác với bản ghi
*/
class CRecord
{
	public $data;
	/**
	 * Hàm khởi tạo, nó sẽ khởi tạo một đối tượng mảng
	 */
	function __construct($data=array())
	{
		if(is_object($data) and ($data instanceof CTable))
		{
			if($data->record)
			{
				$this->data = $data->record->data;
			}
		}
		else
		{
			$this->data = $data;
		}
	}
	/**
	 * Hàm "__get" dùng để đọc giá trị từ một biến chưa được định nghĩa ($name)
	 *
	 * @param string $name là biến tên bản ghi dữ liệu
	 * @return ref $this->data[$name] trả về giá trị mảng data có key là biến $name 
	 * @return ref $this->$name trả về tên biến
	 */
    public function __get($name)
    {
        if (isset($this->data[$name])) {
            return $this->data[$name];
        } elseif(isset($this->$name)) {
			return $this->$name;
        }
		return false;
    }
	/**
	 * Hàm "__set" dùng để gán giá trị của biến $val vào biến $name hoặc vào data[$name]
	 *
	 * @param string $name là biến tên bản ghi chưa được định nghĩa của lớp CRecord
	 * @param string $val 
	 * 
	 */
    public function __set($name, $val)
    {
        if (isset($this->$name)) {
			$this->$name = $val;
		}
		else
		{
            $this->data[$name] = $val;
        }
    }
	/**
	 * Hàm isset kiểm tra biến $name
	 *
	 * @param $name 
	 * @return nếu tồn tại biến name thì trả về true,nếu không trả về data[$name]
	 * 
	 */
    public function __isset($name)
    {
        return isset($this->$name)?true:isset($this->data[$name]);
    }
	/**
	 * Hàm __unset dùng để huỷ biến $name,remove phần tử có key là name trong mảng data
	 */
    public function __unset($name)
    {
        unset($this->data[$name]);
    }
    
    public function test($conditions)
    {
		if($conditions and is_array($conditions))
		{
			foreach($conditions as $key=>$value)
			{
				if(is_array($this->data))
				{
					if(!isset($this->data[$key]) or $this->data[$key] != $value)
					{
						return false;
					}
				}
				elseif(is_object($this->data))
				{
					if(!isset($this->data->$key) or $this->data->$key != $value)
					{
						return false;
					}
				}
			}
		}
		if($conditions and is_object($conditions))
		{
			switch ($conditions->operator) {
				case 'ID':
					if($conditions->factors[0] != $this->id)
					{
						return false;
					}
					break;
				case 'AND':
					foreach($conditions->factors as $factor)
					{
						if(!$this->test($factor))
						{
							return false;
						}
					}
					break;
				case 'OR':
					foreach($conditions->factors as $factor)
					{
						if($this->test($factor))
						{
							return true;
						}
					}
					break;
				case '!':
					return !$this->test_value($conditions->factors[0]);
				default:
					if(sizeof($conditions->factors)>1)
					{
						$left = $this->test_value($conditions->factors[0]);
						$right = $this->test_value($conditions->factors[1]);
						eval('$ok = '.$left.' '.$conditions->operator.' '.$right.';');
						return $ok;
					}
					break;
			}
		}
    	return true;
    }
    /**
     * Hàm test_value có tham biến $expr
     *
     * 
     * @return trả về giá trị mảng data
     */
    function test_value($expr)
    {
    	if(is_string($expr))
    	{
    		if(isset($this->data[$expr]))
    		{
    			return $this->data[$expr];
    		}
    	}
    	elseif(is_object($expr))
    	{
    		switch ($conditions->operator) {
				case 'STRING':
				case 'INT':
				case 'FLOAT':
				case 'BOOL':
					return $conditions->factors[0];
    		}
    	}
    }
	function  setting($name, $default = false)
	{
		return isset($this->settings[$name])?$this->settings[$name]:$default;
	}
	function set_setting($name, $value)
	{
		$this->settings[$name] = $value;
	}
}
/**
 * Hàm CRecord 
 *
 * @param  $data là một đối tượng mảng
 * @return trả về một Bản ghi các đối tượng
 */
function CRecord($data = array())
{
	return new CRecord($data);
}
?>